﻿namespace DotNetUtility.GenericDesignPattern
{
    using System;

    /// <summary>
    /// To get a service instance on basis of provided condition.
    /// </summary>
    /// <example>
    ///     <code>
    ///         class Program
    ///         {
    ///             static void Main(string[] args)
    ///             {
    ///                 var proxyA = ServiceFactory.ServiceInstanceOf<IPerson, PersonA, PersonB>(BusinessLogicPersonASelection);
    ///                 var proxyB = ServiceFactory.ServiceInstanceOf<IPerson, PersonA, PersonB>(BusinessLogicPersonBSelection);
    ///             }
    ///             static bool BusinessLogicPersonASelection()
    ///             { return true; }
    ///             static bool BusinessLogicPersonBSelection()
    ///             { return default(bool); }
    ///         }
    ///         public interface IPerson { string FindPersonName();}
    ///         public class PersonA : IPerson
    ///         {
    ///             public string FindPersonName()
    ///             { return "A"; }
    ///         }
    ///         public class PersonB : IPerson
    ///         {
    ///             public string FindPersonName()
    ///             { return "B"; }
    ///         }
    ///     </code>
    /// </example>
    public static class ServiceFactory
    {
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T1">Interface type of T2 and T3 types.</typeparam>
        /// <typeparam name="T2">Implementor of interface T1</typeparam>
        /// <typeparam name="T3">Implementor of interface T1</typeparam>
        /// <param name="chooseWhichOneToGet">It is business logic block to select the appropiate type from the T2 and T3</param>
        /// <returns>Either T2 or T3 based on the chooseWhichOneToGet</returns>
        /// <example>
        ///     <code>
        ///           var proxyA = ServiceFactory.ServiceInstanceOf<IPerson, PersonA, PersonB>(BusinessLogicPersonASelection);
        ///           var proxyB = ServiceFactory.ServiceInstanceOf<IPerson, PersonA, PersonB>(BusinessLogicPersonBSelection);
        ///     </code>
        /// </example>
        /// Contributed by Mohammad Rahman
        public static T1 ServiceInstanceOf<T1, T2, T3>(Func<bool> chooseWhichOneToGet)
            where T2 : T1, new()
            where T3 : T1, new()
        {
            return chooseWhichOneToGet() ? ((T1)new T2()) : ((T1)new T3());
        }
    }
}
